const fs = require('fs');
const path = require('path');
const http = require('http')

const HttpClient = require('../util/HttpClient')
const ROOT_PATH = path.resolve(__dirname, '../../')

/**
 * @description: 获取本地文件是否存在
 * @param {*} context 上下文
 * @param {String} script 文件名称
 * @return {Promise<Boolean>} 是否存在的状态
 */
async function getLocalScriptFileIsExist(context, scriptName) {
  
  // 文件是否存在
  let isFileExist = false
  // 主机地址
  let host = context && context.request && context.request.header && context.request.header.host
  // 请求地址
  let url = `http://${host}${scriptName}`
  
  return (
    new Promise((resolve, reject) => {
      http
        .get(url, (res) => {
          isFileExist = res.statusCode != 404
          resolve(isFileExist)
        })
        .on('error', (error) => {
          isFileExist = false
          console.error(`Got error: ${error.message}`)
          resolve(isFileExist)
        })
    })
  )
  
}

/**
 * @description: 获取此模块选择启动
 * @param {*} context 上下文
 * @param {String} script 文件名称
 * @return {Promise<Boolean>} 是否存在的状态
 */
function getEntryIsSelectedStart(context, scriptName) {
  
  if (!global.webpackConfig) return
  
  const entry = global.webpackConfig.entry
  const entryKeys = Object.keys(entry)
  
  return entryKeys.some(key => scriptName.includes(key))
  
}

function getEntryIsSelectedJs(context, scriptName) {
  if (!global.webpackConfig) return

  const entry = global.webpackConfig.entry
  // 去除.js为空以及/ 符号实现精准匹配
  scriptName = scriptName.replace('.js', '').substring(1)

  let jsUrl = ''

  for(let [key, val] of Object.entries(entry)){
    if(scriptName === key) {
      jsUrl = val[0].substring(1)
      break
    }
  }
  return jsUrl
}

function isViteEnv() {
  const args = process.argv
  return args.find(item=> item.includes('vite'))
}

function setIsProductionProxy(js) {
  try {
    // eslint-disable-next-line quotes
    const initJSON = js.trim().replace(`window._init = '`, '').replace(`';`, '')
    const initData = JSON.parse(initJSON) || {}
    const env = initData.env
    
    const isProductProxy = ['multi_prod', 'production'].includes(env)
    
    if (isProductProxy) {
      global.isProductProxy = isProductProxy
    }
    
  } catch(error) {
    // 
  }
}

function insetProdTipElement(template, isEntrySelectedStart) {
  // 下面代码大部分是自动生成的
  let script = `
  <script>
    let prodTipElement = document.createElement('div')
    prodTipElement.innerHTML = '请注意，现在访问的页面是生产环境的，操作时请注意是否可以修改！！'
    prodTipElement.style.position = 'fixed'
    prodTipElement.style.top = '${isEntrySelectedStart ? 0 : '18px'}'
    prodTipElement.style.left = '0'
    prodTipElement.style.width = '50%'
    prodTipElement.style.marginLeft = '25%'
    prodTipElement.style.height = '18px'
    prodTipElement.style.backgroundColor = '#f00'
    prodTipElement.style.color = '#fff'
    prodTipElement.style.zIndex = '9999'
    prodTipElement.style.textAlign = 'center'
    prodTipElement.style.lineHeight = '18px'
    prodTipElement.style.fontSize = '12px'
    document.body.appendChild(prodTipElement)
  </script>
  `
  const bodyEndTag = '</body>'
  const bodyEndIndex = template.indexOf(bodyEndTag)
  
  return template.substring(0, bodyEndIndex) + script + template.substring(bodyEndIndex)
}

function insetDevTipElement(template) {
  // 下面代码大部分是自动生成的
  let script = `
  <script>
    let tipElement = document.createElement('div')
    tipElement.innerHTML = '请注意，现在访问的页面是通过代理访问的，不是实际的本地页面！！'
    tipElement.style.position = 'fixed'
    tipElement.style.top = '0'
    tipElement.style.left = '0'
    tipElement.style.width = '50%'
    tipElement.style.marginLeft = '25%'
    tipElement.style.height = '18px'
    tipElement.style.backgroundColor = '#f00'
    tipElement.style.color = '#fff'
    tipElement.style.zIndex = '9999'
    tipElement.style.textAlign = 'center'
    tipElement.style.lineHeight = '18px'
    tipElement.style.fontSize = '12px'
    document.body.appendChild(tipElement)
  </script>
  `
  const bodyEndTag = '</body>'
  const bodyEndIndex = template.indexOf(bodyEndTag)
  
  return template.substring(0, bodyEndIndex) + script + template.substring(bodyEndIndex)
}

module.exports = {
  async renderWithHtml(title, html = '', script, templatePath = 'src/templates/index.html', context, isShowPageLoading = false) {
    let js = this.parseHtml(html);
    return this.render(title, js, script, templatePath, context, isShowPageLoading);
  },
  renderWithData(title, data = {}, script, templatePath = 'src/templates/index.html', context, isShowPageLoading = false){
    let js = `window._init = '${JSON.stringify(data)}';`
    return this.render(title, js, script, templatePath, context, isShowPageLoading);
  },
  /** 渲染模板（开发用） */
  async render(title = '售后宝', js, script, templatePath = 'src/templates/index.html', context, isShowPageLoading) {
    let buffer = fs.readFileSync(path.resolve(ROOT_PATH, templatePath), 'utf-8');
    let template = buffer.toString()

    // 如果配置了页面级loading（isShowPageLoading=true），就将html页面加入loading的dom，否则去除模版中的占位符
    let pageLoadingHtml = isShowPageLoading ? '<div id="loader-wrapper"><svg viewBox="25 25 50 50" class="circular"><circle cx="50" cy="50" r="20" fill="none" class="path"></circle></svg></div>' : ''
    template = template.replace('<%= htmlWebpackPlugin.options.isShowPageLoading %>', pageLoadingHtml)
    

    if(isViteEnv()) {
      template = await global.vite.transformIndexHtml(context.req.url, template)
    }
  
    // 注入标题
    template = template.replace('#{title}', title)
    
    
    // 注入参数
    template = template.replace('<script data-init="js">window._init = \'#{initJson}\';</script>', `<script data-init="js">${js}</script>`);

    // 注入脚本
    if(Array.isArray(script) && script.length > 0) {
      let scriptHtml = '';
 
      if(isViteEnv()) { 
        scriptHtml += `<script type="module" src="${getEntryIsSelectedJs(context, script[0])}"></script><script>window.IS_VITE=true</script>`
      } else {
        script.forEach(item => scriptHtml += `<script src="${item}"></script>`)
      }

      scriptHtml += '</body>';
      
      template = template.replace('</body>', scriptHtml)

      if(!isViteEnv()) {
        
        setIsProductionProxy(js)
        
        const isEntrySelectedStart = getEntryIsSelectedStart(context, script[0])
        const isProductProxy = global.isProductProxy
        
        if (!isEntrySelectedStart) {
          template = await HttpClient.proxyForRender(context)
          template = insetDevTipElement(template, isProductProxy)
        }
        
        if (isProductProxy) {
          template = insetProdTipElement(template, isEntrySelectedStart)
        } 
      }
      
    }
    
    return template
    
  },
  /** 提取script中的数据 */
  parseHtml(html){
    let scriptReg = /<script data-init="js">(.*?)<\/script>/;
    let result = scriptReg.exec(html);
    
    return result ? result[1] : null;
  }
}